<?php

namespace App\Services\Permission;

use App\Dao\Permission\AdminDao;
use App\Exceptions\BadException;
use App\Extends\BaseService;
use App\Helpers\Jwt;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Cache;

class AdminService extends BaseService
{
    public function __construct(AdminDao $dao)
    {
        parent::__construct($dao);
        $this->dao = $dao;
    }

    /**
     * 保存新增管理员
     * @param array $data
     * @return mixed
     * @throws \Exception
     */
    public function create(array $data): mixed
    {
        return $this->transactional(function () use ($data) {
            if(isset($data['roles'])) {
                $data['roles'] = ensureArray($data['roles']);
            }
            return $this->dao->create($data);
        });
    }

    /**
     * 编辑管理员
     * @param int $id
     * @param array $data
     * @return mixed
     * @throws \Exception
     */
    public function update(int $id, array $data): mixed
    {
        return $this->transactional(function () use ($data, $id) {
            if(isset($data['roles'])) {
                $data['roles'] = ensureArray($data['roles']);
                // $data['roles'] = implode(',', $dataArr); 模型设置了类型转换，这里可以忽略
            }
            if(empty($data['password'])) {
                unset($data['password']);
            }
            return $this->dao->update($id, $data);
        });
    }

    /**
     * 根据管理员ID查找路由菜单
     * @param $admin_id
     * @return array
     */
    public function getMenus($admin_id)
    {
        // 生成缓存键
        $cacheKey = "menus:admin_{$admin_id}";

        // 尝试从缓存中获取数据
        // return Cache::remember($cacheKey, 60 * 60 * 1, function () use ($admin_id) {
            // 当前管理员信息
            $adminInfo = $this->dao->find($admin_id);
            if(empty($adminInfo)) {
                throw new BadException('管理员不存在!');
            }
            // 获取角色Ids
            $roleIds = $adminInfo->roles;
            if(empty($roleIds)) {
                return [];
            }
            $roleService = app(RoleService::class);
            $roles = $roleService->findByConditions(['id' => ['in', $roleIds]]);
            // 创建权限规则数组
            $ruleIds = [];
            foreach ($roles as $role) {
                if (isset($role['rules']) && is_array($role['rules'])) {
                    // 合并角色权限数组
                    $ruleIds = array_merge($ruleIds, $role['rules']);
                }
            }
            // 使用 array_filter 去掉空值
            $ruleIds = array_filter($ruleIds, function ($value) {
                return !empty($value) || $value === '0';
            });
            // 去掉重复值
            $ruleIds = array_unique($ruleIds);
            $menuService = app(MenuService::class);
            if($admin_id === 1) {
                // 超级管理员获取全部菜单
                $menuData = $menuService->findByConditions(['status' => 1])->toArray();
            } else {
                $menuData = $menuService->findByConditions(['id' => ['in', $ruleIds], 'status' => 1])->toArray();
            }
            return buildMenuTree($menuData);
        // });
    }

    /**
     * 登录
     * @param $account
     * @param $password
     * @return mixed
     */
    public function login($account, $password)
    {
        $adminUser = $this->dao->findByConditions(['account' => $account, 'status' => 1], [], ['*'], true);
        if($adminUser && Hash::check($password, $adminUser->password)) {
            // 验证成功，生成token
            return [
                'accessToken' => Jwt::getInstance()->createToken(['admin_id' => $adminUser->id, 'username' => $adminUser->username, 'account' => $adminUser->account]),
            ];
        } else {
            throw new BadException('账号或密码错误请重试！', 422);
        }
    }

    /**
     * 获取管理员、角色、权限菜单信息
     * @param $admin_id
     * @return mixed
     */
    public function getInfo($admin_id)
    {
        $adminInfo = $this->dao->find($admin_id);
        $roleService = app(RoleService::class);
        $roleMake = $roleService->findColumns([['id', 'in', $adminInfo['roles']], ['status', '=', 1]], 'mark')->toArray();
        // 去掉重复角色标识
        $adminInfo['roles'] = array_unique($roleMake);
        return $adminInfo;
    }

    /**
     * 获取管理员权限码
     */
    public function getCodes($admin_id)
    {
        // 当前管理员信息
        $adminInfo = $this->dao->find($admin_id);
        if(empty($adminInfo)) {
            throw new BadException('管理员不存在!');
        }
        // 获取角色Ids
        $roleIds = $adminInfo->roles;
        if(empty($roleIds)) {
            return [];
        }
        $roleService = app(RoleService::class);
        $roles = $roleService->findByConditions(['id' => ['in', $roleIds]]);
        // 创建权限规则数组
        $ruleIds = [];
        foreach ($roles as $role) {
            if (isset($role['rules']) && is_array($role['rules'])) {
                // 合并角色权限数组
                $ruleIds = array_merge($ruleIds, $role['rules']);
            }
        }
        // 使用 array_filter 去掉空值
        $ruleIds = array_filter($ruleIds, function ($value) {
            return !empty($value) || $value === '0';
        });
        // 去掉重复值
        $ruleIds = array_unique($ruleIds);
        $menuService = app(MenuService::class);
        $menuData = $menuService->findColumns([['id', 'in', $ruleIds], ['status', '=', 1]], 'perms')->toArray();
        return $menuData;
    }
}
